<?php
class WebsocketTest {
    public $server;
    public $redis;
    //user 保存的是用户的信息
	//ws_user_live 保存websocket_id与用户的关系。hash类型
	//ws_room_live 保存房间与websocket_id的关系。set类型
	//ws_map_live  保存websocket_id与房间的关系。hash类型
    public function __construct() {
        $this->server = new Swoole\WebSocket\Server("0.0.0.0", 9502);
		$this->redis = new Redis();
		$connect_stuats = $this->redis->connect('127.0.0.1', 6379);
		if($connect_stuats)
		{
			echo '连接Redis成功！';
		}else{
			echo '连接Redis失败！';
		}
		//清空 ws_user_live ws_room_live ws_map_live
		$this->redis->del('ws_user_live');
		$this->redis->delete($this->redis->keys('ws_room_live*'));
		$this->redis->del('ws_map_live');

        $this->server->on('open', function (swoole_websocket_server $server, $request) {
        	echo "用户：“{$request->fd}” 进来啦！\n";
        });
        $this->server->on('message', function (Swoole\WebSocket\Server $server, $frame) {
        	 echo "{$frame->fd}说:{$frame->data},opcode:{$frame->opcode},fin:{$frame->finish}\n";
			 //解析收到的数据
			 $receive_data = json_decode($frame->data);

			 //ws绑定user_id;
			 $this->redis->hSet('ws_user_live',$frame->fd,$receive_data->user_id);
			 //把ws_id保存在房间
			 $is_join = $this->redis->sAdd('ws_room_live:'.$receive_data->room_id,$frame->fd);
			 echo $is_join ? '加入房间成功' : '已经加入房间';

			
			 //添加映射关系
			 $this->redis->hSet('ws_map_live',$frame->fd,$receive_data->room_id);
			 //获取房间所有的websocket_id
			 $room_websocket_ids = $this->redis->sMembers('ws_room_live:'.$receive_data->room_id);
		    //print_r($room_user);

			 if($is_join)
			 {
				//加入的时候推送用户信息给前端
		        $this->get_room_user_list($room_websocket_ids);
			 }
			 
			 //发送消息给用户
		    $data['nickname'] = $receive_data->nickname;
		    $data['data'] = $receive_data->msg;
		    $data['type'] = 'msg';
		    $this->send_msg($room_websocket_ids,$data);
        });
        $this->server->on('close', function ($ser, $fd) {
            echo "用户 {$fd} 离开啦！\n";
			//离开删除ws_id
			$this->redis->hdel('ws_user_live',$fd);
			//根据映射表删除房间里的ws_id
			$room_id = $this->redis->hget('ws_map_live',$fd);
			//删除房间的
			$this->redis->sRem('ws_room_live:'.$room_id,$fd);
			//删除映射关系
			$this->redis->hdel('ws_map_live',$fd);
			//发送用户列表
		    $room_websocket_id_list = $this->redis->sMembers('ws_room_live:'.$room_id);
		    $this->get_room_user_list($room_websocket_id_list);
        });
        $this->server->on('request', function ($request, $response) {
            // 接收http请求从get获取message参数的值，给用户推送
            // $this->server->connections 遍历所有websocket连接用户的fd，给所有用户推送
            foreach ($this->server->connections as $fd) {
                $this->server->push($fd, $request->get['message']);
            }
        });
        $this->server->start();
    }


	//返回房间所有用户
	public function get_room_user_list($room_websocket_ids)
	{
		//获取用户信息
	    foreach($room_websocket_ids as $websocket_id)
	    {
	        $user_id = $this->redis->hGet('ws_user_live',$websocket_id);
	        if (!isset($user_list[$user_id]))
	        {
	            $user_list[$user_id] = (array)json_decode($this->redis->hget('user',$user_id));
	        }
	    }
	    //发送用户列表
	    foreach($room_websocket_ids as $websocket_id)
	    {
	        $user_list_data['data'] = $user_list;
	        $user_list_data['type'] = 'userlist';
	        $this->server->push($websocket_id, json_encode($user_list_data));
	    }
	}

	//向用户发消息
	public function send_msg($websocket_ids,$data)
	{
	    foreach($websocket_ids as $websocket_id)
	    {
	        $this->server->push($websocket_id, json_encode($data));
	    }
	}

}
new WebsocketTest();




//清空 ws_user_live ws_room_live ws_map_live
